

extern float ran1(long *idum);
extern float ran2(long *idum);

// get random integer in range [0, Nmax] inclusive
inline static int getRand( int Nmax, long* seed )
{
	// TO DO: does this return integers in range [0, Nmax] with equal probability of each?
	if (Nmax==0) return 0;
	
	int r = static_cast<int>( static_cast<float>(Nmax+1) * ran2(seed) );
	if (r > Nmax) r = Nmax;
	return r;
}


// primes used by random number generator.
static const unsigned Primes[] = {
    0x9e3779b1, 0xffe6cc59, 0x2109f6dd, 0x43977ab5,
    0xba5703f5, 0xb495a877, 0xe1626741, 0x79695e6b,
    0xbc98c09f, 0xd5bee2b3, 0x287488f9, 0x3af18231,
    0x9677cd4d, 0xbe3a6929, 0xadc6a877, 0xdcf0674b,
    0xbe4d6fe9, 0x5f15e201, 0x99afc3fd, 0xf3f16801,
    0xe222cfff, 0x24ba5fdb, 0x0620452d, 0x79f149e3,
    0xc8b93f49, 0x972702cd, 0xb07dd827, 0x6c97d5ed,
    0x085a3d61, 0x46eb5ea7, 0x3d9910ed, 0x2e687b5b,
    0x29609227, 0x6eb081f1, 0x0954c4e1, 0x9d114db9,
    0x542acfa9, 0xb3e6bd7b, 0x0742d917, 0xe9f3ffa7,
    0x54581edb, 0xf2480f45, 0x0bb9288f, 0xef1affc7,
    0x85fa0ca7, 0x3ccc14db, 0xe6baf34b, 0x343377f7,
    0x5ca19031, 0xe6d9293b, 0xf0a9f391, 0x5d2e980b,
    0xfc411073, 0xc3749363, 0xb892d829, 0x3549366b,
    0x629750ad, 0xb98294e5, 0x892d9483, 0xc235baf3,
    0x3d2402a3, 0x6bdef3c9, 0xbec333cd, 0x40c9520f
};

// A random number generator, uses linear congruential method.
class FastRandom
{
    unsigned x, a;

public:
	
    // Get a random number.
    unsigned short get() 
	{
        unsigned short r = x >> 16;
        x = x*a + 1;
        return r;
    }
	
    // Construct a random number generator.
    FastRandom( unsigned seed )
	{
        x = seed;
        a = Primes[ seed % (sizeof(Primes) / sizeof(Primes[0])) ];
    }
};


inline bool PoissonDecision( float timeElapsed, float averageTimeInterval, long* seed )
{
	float mu = timeElapsed/averageTimeInterval;
	float p = 1.f - expf(-mu);
	float epsilon = ran2(seed);
	return epsilon < p;
}
